#pragma once

#include <iostream>
#include <mutex>

/**
 * @brief 单例模式
 * 模板类 声明和实现都要写在头文件中，否则会链接错误
 * 如果一定要写在cpp文件中，需要 进行模版实例化
 */
namespace tmms
{
    namespace base
    {
        template <typename T>
        class Singleton {
            private:
                Singleton() = default;
                ~Singleton() = default;
                Singleton(const Singleton&) = delete;
                Singleton& operator=(const Singleton&) = delete;
            private:
                static T* instance; 
                static std::once_flag initFlag; 
            public:
                static T*& getInstance()
                 {
                    std::call_once(initFlag, &Singleton::init);
                    return instance;
                 }  
             private:
                static void init()
                {
                    if(!instance)
                    {
                        instance = new T();
                    }
                }    
        };
        //初始化静态变量
        template <typename T>
        T* Singleton<T>::instance = nullptr;

        template <typename T>
        std::once_flag Singleton<T>::initFlag;

    }
}